package mi.controls
{
	import flash.events.Event;
	
	import mi.controls.highlight.*;
	import mi.controls.highlight.impl.*;
	
	import mx.controls.TextArea;

	/**
	 * 
	 * SyntaxEditor组件是一个带有边框和可选滚动条，能根据指定的语言类型高亮输入内容多行文本字段。
	 * <p>当设置type属性或者text属性时，如果text属性不为空白字符串时将重新高亮文本。</p>
	 * <p>属性type《高亮类型》：
	 * <ul>
	 * <li>支持java|sql</li>
	 * <li>默认高亮类型为java</li>
	 * <li>不能设置为空，当设置为空时，忽略该设置,保持前一个设置</li>
	 * </ul>
	 * </p>
	 * 
	 * @author liushimin 2011-7-5
	 * 
	 * 
	 * @see mx.controls.TextArea
	 * 
	 * @langversion 3.0
	 * @playerversion Flash 9
	 * @playerversion AIR 1.1
	 * @productversion Flex 3
	 */
	public class SyntaxEditor extends TextArea
	{
		//高亮类型
		private var _DEFAULT_TYPE:String="java";
		
		private var _type:String=_DEFAULT_TYPE;
		
		public function SyntaxEditor()
		{
			super();
			//绑定highligth事件
			addEventListener(SyntaxEditorEvent.HIGHT_LIGHT_CHANGE,_hightLightHandler);
			//绑定change时触发highligth事件
			addEventListener(flash.events.Event.CHANGE,_dispatchHightLightEvent);
		}
		
		public function get type():String
		{
			return _type;
		}
		
		/**
		 * 高亮类型
		 * 设置高亮类型后，将重新语法高亮文本
		 * <ul>
		 * <li>支持java|sql</li>
		 * <li>默认值为java</li>
		 * <li>不能设置为空，当设置为空时，忽略该设置,保持前一个设置</li>
		 * </ul>
		 *
		 */ 
		public function set type(value:String):void
		{
			if(!isBlank(value)){
				_type = value;
				_dispatchHightLightEvent(null)
			}
		}
		
		/**
		 * 文本内容
		 * 设置文本后，将重新语法高亮文本
		 */ 
		override public function set text(value:String):void
		{
			super.text=value;
			if(!isBlank(value)){
				_dispatchHightLightEvent(null);
			}
		}
		
		/**
		 * 静态方法.为编辑器添加自定义的语法高亮支持.一旦添加，将适用于所有的SyntaxEditor
		 */
		public static function addSupport(type:String,iHightLight:IHightLight):void{
			if(isBlank(type)||null==iHightLight){
				throw "name or iHightLight must not be null";
			}
			_defaultSupport[type.toLowerCase()]=iHightLight;
		}
		
		/**
		 * 高亮文本之前执行
		 */ 
		protected function beforeLightText(value:String):String{
			return value.split("<").join("especialCharacter60");
		}
		
		/**
		 * 高亮文本，在beforeLightText方法执行后执行，将对应的IHightLight实现中的正则替换文本
		 * 如果需要增加额外的个性化的高亮，则覆盖本方法即可
		 */ 
		protected function onLightText(s:String):String{
			var _type:String=trim(type.toLowerCase()),support:IHightLight=_defaultSupport[_type];
			if(null!=support){
				var list:Array=support.regexList;
				for(var i:int=0;i<list.length;i++){
					s=s.replace(list[i].regex,list[i].match);//循环替换支持
				}
			}
			return s;
		}
		
		/**
		 * 高亮文本onLightText后执行
		 */ 
		protected function afterLightText(s:String):String{
			/*return word 回车*/
			s="<p>"+s.replace(HLConstant.REGEX_RETURN,"</p><p>")+"</p>";
			//修正每次自动增加一行的错误
			if(s.substr(s.length-7,s.length)=='<p></p>'){
				s=s.substring(0,s.length-7);
			}
			//s=s.replace(new RegExp("<p></p>","g"),"");如果使用本语句则不允许多次换行
			return s.split("especialCharacter60").join("&#60;");
		}
		
		private static function trim(value:String):String{
			return value.replace(/(^\s*)|(\s*$)/g, "");
		}
		
		private static function isBlank(value:String):Boolean{
			return null==value||trim(value)=="";
		}
		
		//默认支持
		private static var _defaultSupport:Object={
			"sql" : new SqlHightLightImpl(),
			"java": new JavaHightLightImpl(),
			"csharp" : new CSharpHightLightImpl(),
			"javascript" : new JavaScriptHightLightImpl()
		}

		private function _dispatchHightLightEvent(event:Event):void
		{
			dispatchEvent(new SyntaxEditorEvent(SyntaxEditorEvent.HIGHT_LIGHT_CHANGE));
		}
		
		/**
		 *  @private
		 */
		private function _hightLightHandler(event:Event):void
		{
			if(isBlank(type)||isBlank(text)){
				return;
			}
			var _type:String=trim(type.toUpperCase()),s:String=text;
			s=beforeLightText(s);
			s=onLightText(s);
			s=afterLightText(s);
			htmlText=s;
		}
		
	}
}